package per.srp.demo.carLink.Utils;

import com.alibaba.fastjson.JSONObject;
import per.srp.demo.carLink.entity.Car;

import java.util.Properties;
import java.util.Random;

/**
 * 用于加密与解密小车传递的数据
 * 标准格式：(不允许有任何空格与回车)

 {
    "code":"1123123213",  //固定10位数字 index:9-18
     "no":"12345",
     "lon":123.123123,
     "lat":123.123123,
     "v":12.3,
     "b":30
 }

 {
    "code":"1123123213",
    ”command":"A",
    "time":3,
 }
 */
public class CarInfoCodeTool {
    public static final String CAR_INFO_LEGAL_REGX="[^\\da-zA-Z0-9\\.\\:\\\"\\,\\{\\}\\[\\]]+";
    public static final char CAR_ENCODE_BASE_CHAR='<';

    /**
     * 删除非字符集字符串
     * @param inputStr
     * @return
     */
    private static String removeIllegalChar(String inputStr){
        return inputStr.replaceAll(CAR_INFO_LEGAL_REGX,"");
    }


    /**
     * 将字符串加密
     输入格式：
     {
         "code":"1123123213",  //固定10位数字 index:9-18
         ...
     }
     * @param jsonInfoString 信息字符串
     * @return 加密密之后的字符串
     */
    public static String enCodeString(String jsonInfoString){
        if(jsonInfoString==null) return null;

        StringBuffer infoStringBuffer = new StringBuffer(removeIllegalChar(jsonInfoString));
        if (infoStringBuffer.length()<21) return null;

        char ch,currentCh;

        //单独加密 秘文
        StringBuffer code = new StringBuffer("");
        for(int i=9;i<=18;i++){
            currentCh = infoStringBuffer.charAt(i);
            if(currentCh<'0'||currentCh>'9') throw new IllegalArgumentException("code must be number.");

            code.append(currentCh);

            ch = (char)(currentCh-'0'+CAR_ENCODE_BASE_CHAR);
            infoStringBuffer.setCharAt(i,ch);
        }

        //利用秘文加密整个json
        int[] codeIndexArray={
          1,2,3,4,5,6,7,8,9,0
        };
        int len = infoStringBuffer.length();
        int index = 0;
        for(int i=0;i<len;i++){
            if(i>=9&&i<=18) continue;//不加密密文

            ch = (char)(infoStringBuffer.charAt(i)+(code.charAt(index)-'0'));
            index=codeIndexArray[index];//循环0~9

            infoStringBuffer.setCharAt(i,ch);
        }
        return infoStringBuffer.toString();
    }


    /**
     * 将加密字符串解密为json格式字符串
     * @param enCodeString 被加密的字符串
     * @return 解密之后的json字符串
     */
    public static String deCodeString(String enCodeString){
        if(enCodeString==null) return null;

        StringBuffer enCodeStringBuffer = new StringBuffer(enCodeString);
        if (enCodeStringBuffer.length()<21) return null;

        char ch;

        //解密密文
        StringBuffer code = new StringBuffer("");
        for(int i=9;i<=18;i++){
            ch = (char)(enCodeStringBuffer.charAt(i)+'0'-CAR_ENCODE_BASE_CHAR);
            if(ch<'0'||ch>'9') return null;
            code.append(ch);
            enCodeStringBuffer.setCharAt(i,ch);
        }

        //利用密文解密json
        int[] codeIndexArray={
                1,2,3,4,5,6,7,8,9,0
        };
        int len = enCodeStringBuffer.length();
        int index = 0;
        for(int i=0;i<len;i++){
            if(i>=9&&i<=18) continue;

            ch = (char)(enCodeStringBuffer.charAt(i)-(code.charAt(index)-'0'));
            index=codeIndexArray[index];

            enCodeStringBuffer.setCharAt(i,ch);
        }
        return enCodeStringBuffer.toString();
    }

    /**
     * 解密并且封装到JSONObject
     * @param codeStr 加密字符串
     * @return 解密的 JSONObject
     */
    public static JSONObject deCodeToJSONObject(String codeStr){
        try {
            codeStr = deCodeString(codeStr);
            JSONObject json = JSONObject.parseObject(codeStr);
            return json;
        }catch (Exception e){

        }
        return null;
    }

    /**
     * 加密JSONObject到字符串
     * @param InfoP 包含信息的 JSONObject
     * @return
     */
    public static String enCodeJSONObject(JSONObject InfoP){
        String code = InfoP.getString("code");
        InfoP.remove("code");
        StringBuffer oldJsonString = new StringBuffer(removeIllegalChar(InfoP.toJSONString()));
        oldJsonString.deleteCharAt(0);
        String newJsonString;
        if(oldJsonString.charAt(0)=='}'){
            newJsonString = "{"+"\"code\":\""+code+"\"}";
        }else{
            newJsonString = "{"+"\"code\":\""+code+"\""+","+oldJsonString;
        }
        InfoP.put("code",code);
        return enCodeString(newJsonString);
    }

//    public static void main(String[] args) {
//        String jsonStr = "{\n" +
//                " \"code\":\"1232223289\",\n" +
//                " \"no\":\"12345\",\n" +
//                " \"lon\":0.0,\n" +
//                " \"lat\":0.0,\n" +
//                " \"v\":0.0,\n" +
//                " \"b\":0\n" +
//                " }";
//        String encodeStr = enCodeString(jsonStr); //将json加密
//        String decodeStr = deCodeString(encodeStr);
//        System.out.println("加密后： ["+encodeStr+"]");
//        System.out.println("解密后： ["+decodeStr+"]");
//
//        JSONObject jo = deCodeToJSONObject(encodeStr); //解密并且封装到JSONObject
//        String encodeStringFromJSONObject = enCodeJSONObject(jo);//将JSONObject转json并且加密到字符串
//
//        //如果jo与jo2内容一样，说明加解密成功
//        JSONObject jo2 = deCodeToJSONObject(encodeStringFromJSONObject); //解密并且封装到JSONObject
//
//    }


    private static char[] chars = {'0','1','2','3','4','5','6','7','8','9'};
    public static String randomNumbers(int len){
        StringBuffer stringBuffer = new StringBuffer("");
        Random random = new Random();
        for(int i=0;i<len;i++){
            stringBuffer.append(chars[random.nextInt(10)]);
        }

        return stringBuffer.toString();
    }
}
